home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / glx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  41.2 KB  |  1,563 lines

  1. /* $Id: glx.c,v 1.13 1997/03/11 01:31:39 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: glx.c,v $
  26.  * Revision 1.13  1997/03/11 01:31:39  brianp
  27.  * changed version strings to 2.2
  28.  *
  29.  * Revision 1.12  1997/02/27 20:02:40  brianp
  30.  * better visual creation error checking (Alex Harper)
  31.  *
  32.  * Revision 1.11  1997/01/31 20:38:49  brianp
  33.  * in find_glx_visual(), try to match new vishandle instead of visinfo
  34.  *
  35.  * Revision 1.10  1997/01/29 19:34:47  brianp
  36.  * replaced is_overlay_visual() with level_of_visual()
  37.  *
  38.  * Revision 1.9  1997/01/29 19:23:31  brianp
  39.  * fixed memory leaks per Wolfram Gloger
  40.  *
  41.  * Revision 1.8  1996/12/09 22:33:53  brianp
  42.  * faster window_exists() function from Stephane Rehel
  43.  *
  44.  * Revision 1.7  1996/11/21 03:40:56  brianp
  45.  * 32-bit per pixel visuals now work
  46.  *
  47.  * Revision 1.6  1996/10/31 01:01:43  brianp
  48.  * added ancillary buffer garbage collection
  49.  * incremented version to 2.1
  50.  *
  51.  * Revision 1.5  1996/09/27 17:09:15  brianp
  52.  * fixed a few warnings about unreachable breaks and returns
  53.  *
  54.  * Revision 1.4  1996/09/27 01:27:01  brianp
  55.  * removed unused variables
  56.  *
  57.  * Revision 1.3  1996/09/19 03:42:38  brianp
  58.  * fixed bug in glXGetCurrentDrawable()
  59.  *
  60.  * Revision 1.2  1996/09/19 03:16:50  brianp
  61.  * re-implemented for new X/Mesa interface, added glXReleaseBuffersMESA()
  62.  *
  63.  * Revision 1.1  1996/09/13 01:38:16  brianp
  64.  * Initial revision
  65.  *
  66.  */
  67.  
  68.  
  69. /*
  70.  * A pseudo-GLX implementation to allow OpenGL/GLX programs to work with Mesa.
  71.  *
  72.  * Thanks to the contributors:
  73.  *
  74.  * Initial version:  Philip Brown (philb@CSUA.Berkeley.EDU)
  75.  * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu)
  76.  * Further visual-handling refinements: Wolfram Gloger
  77.  *    (wmglo@Dent.MED.Uni-Muenchen.DE).
  78.  */
  79.  
  80.  
  81.  
  82. #include <stdio.h>
  83. #include <stdlib.h>
  84. #include <string.h>
  85. #include <X11/Xlib.h>
  86. #include <X11/Xutil.h>
  87. #include "GL/gl.h"
  88. #include "GL/glx.h"
  89. #include "GL/xmesa.h"
  90. #include "context.h"
  91. #include "config.h"
  92. #include "macros.h"
  93. #include "types.h"
  94. #include "xmesaP.h"
  95.  
  96.  
  97.  
  98. #define DONT_CARE -1
  99.  
  100.  
  101.  
  102. #define MAX_VISUALS 100
  103. static XMesaVisual VisualTable[MAX_VISUALS];
  104. static int NumVisuals = 0;
  105.  
  106.  
  107. #define MAX_BUFFERS 1000
  108. static XMesaBuffer BufferList[MAX_BUFFERS];
  109. static int NumBuffers = 0;
  110.  
  111.  
  112.  
  113. /*
  114.  * This struct and some code fragments borrowed
  115.  * from Mark Kilgard's GLUT library.
  116.  */
  117. typedef struct _OverlayInfo {
  118.   /* Avoid 64-bit portability problems by being careful to use
  119.      longs due to the way XGetWindowProperty is specified. Note
  120.      that these parameters are passed as CARD32s over X
  121.      protocol. */
  122.   long overlay_visual;
  123.   long transparent_type;
  124.   long value;
  125.   long layer;
  126. } OverlayInfo;
  127.  
  128.  
  129.  
  130. /* Macro to handle c_class vs class field name in XVisualInfo struct */
  131. #if defined(__cplusplus) || defined(c_plusplus)
  132. #define CLASS c_class
  133. #else
  134. #define CLASS class
  135. #endif
  136.  
  137.  
  138.  
  139.  
  140. /*
  141.  * Test if the given XVisualInfo is usable for Mesa rendering.
  142.  */
  143. static GLboolean is_usable_visual( XVisualInfo *vinfo )
  144. {
  145.    switch (vinfo->CLASS) {
  146.       case StaticGray:
  147.       case GrayScale:
  148.          /* Any StaticGray/GrayScale visual works in RGB or CI mode */
  149.          return GL_TRUE;
  150.       case StaticColor:
  151.       case PseudoColor:
  152.      /* Any StaticColor/PseudoColor visual of at least 4 bits */
  153.      if (vinfo->depth>=4) {
  154.         return GL_TRUE;
  155.      }
  156.      else {
  157.         return GL_FALSE;
  158.      }
  159.       case TrueColor:
  160.       case DirectColor:
  161.      /* Any depth of TrueColor or DirectColor works in RGB mode */
  162.      return GL_TRUE;
  163.       default:
  164.      /* This should never happen */
  165.      return GL_FALSE;
  166.    }
  167. }
  168.  
  169.  
  170.  
  171. /*
  172.  * Return the level (overlay, normal, underlay) of a given XVisualInfo.
  173.  * Input:  dpy - the X display
  174.  *         vinfo - the XVisualInfo to test
  175.  * Return:  level of the visual:
  176.  *             0 = normal planes
  177.  *            >0 = overlay planes
  178.  *            <0 = underlay planes
  179.  */
  180. static int level_of_visual( Display *dpy, XVisualInfo *vinfo )
  181. {
  182.    Atom overlayVisualsAtom;
  183.    OverlayInfo *overlay_info = NULL;
  184.    int numOverlaysPerScreen;
  185.    Status status;
  186.    Atom actualType;
  187.    int actualFormat;
  188.    unsigned long sizeData, bytesLeft;
  189.    int i;
  190.  
  191.    /*
  192.     * The SERVER_OVERLAY_VISUALS property on the root window contains
  193.     * a list of overlay visuals.  Get that list now.
  194.     */
  195.    overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
  196.    if (overlayVisualsAtom == None) {
  197.       return 0;
  198.    }
  199.  
  200.    status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
  201.                                overlayVisualsAtom, 0L, (long) 10000, False,
  202.                                overlayVisualsAtom, &actualType, &actualFormat,
  203.                                &sizeData, &bytesLeft,
  204.                                (unsigned char **) &overlay_info );
  205.  
  206.    if (status != Success || actualType != overlayVisualsAtom ||
  207.        actualFormat != 32 || sizeData < 4) {
  208.       /* something went wrong */
  209.       XFree(overlay_info);
  210.       return 0;
  211.    }
  212.  
  213.    /* search the overlay visual list for the visual ID of interest */
  214.    numOverlaysPerScreen = sizeData / 4;
  215.    for (i=0;i<numOverlaysPerScreen;i++) {
  216.       OverlayInfo *ov;
  217.       ov = overlay_info + i;
  218.       if (ov->overlay_visual==vinfo->visualid) {
  219.          /* found the visual */
  220.          if (/*ov->transparent_type==1 &&*/ ov->layer!=0) {
  221.             int level = ov->layer;
  222.             XFree(overlay_info);
  223.             return level;
  224.          }
  225.          else {
  226.             XFree(overlay_info);
  227.             return 0;
  228.          }
  229.       }
  230.    }
  231.  
  232.    /* The visual ID was not found in the overlay list. */
  233.    XFree(overlay_info);
  234.    return 0;
  235. }
  236.  
  237.  
  238.  
  239.  
  240. /*
  241.  * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
  242.  * configuration in our list of GLX visuals.
  243.  */
  244. static XMesaVisual
  245. save_glx_visual( Display *dpy, XVisualInfo *vinfo,
  246.                  GLboolean rgb, GLboolean alpha, GLboolean dbl,
  247.                  GLint depth_size, GLint stencil_size,
  248.                  GLint accum_size, GLint level )
  249. {
  250.    GLboolean ximage_flag = GL_TRUE;
  251.    XMesaVisual xmvis;
  252.  
  253.    if (NumVisuals>=MAX_VISUALS) {
  254.       fprintf( stderr, "GLX Error: maximum number of visuals exceeded\n");
  255.       return NULL;
  256.    }
  257.  
  258.    if (dbl) {
  259.       /* Check if the MESA_BACK_BUFFER env var is set */
  260.       char *backbuffer = getenv("MESA_BACK_BUFFER");
  261.       if (backbuffer) {
  262.          if (backbuffer[0]=='p' || backbuffer[0]=='P') {
  263.             ximage_flag = GL_FALSE;
  264.          }
  265.          else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
  266.             ximage_flag = GL_TRUE;
  267.          }
  268.          else {
  269.             fprintf(stderr, "Mesa: invalid value for MESA_BACK_BUFFER ");
  270.             fprintf(stderr, "environment variable, using an XImage.\n");
  271.          }
  272.       }
  273.    }
  274.  
  275.    xmvis = XMesaCreateVisual( dpy, vinfo, rgb, alpha, dbl, ximage_flag,
  276.                               depth_size, stencil_size, accum_size, level );
  277.    if (xmvis) {
  278.       VisualTable[NumVisuals] = xmvis;
  279.       NumVisuals++;
  280.    }
  281.    return xmvis;
  282. }
  283.  
  284.  
  285.  
  286. /*
  287.  * Create a GLX visual from a regular XVisualInfo.
  288.  */
  289. static XMesaVisual
  290. create_glx_visual( Display *dpy, XVisualInfo *visinfo )
  291. {
  292.    int vislevel;
  293.  
  294.    vislevel = level_of_visual( dpy, visinfo );
  295.    if (vislevel) {
  296.       /* Configure this visual as a CI, single-buffered overlay */
  297.       return save_glx_visual( dpy, visinfo,
  298.                               GL_FALSE,  /* rgb */
  299.                               GL_FALSE,  /* alpha */
  300.                               GL_FALSE,  /* double */
  301.                               0,         /* depth bits */
  302.                               0,         /* stencil bits */
  303.                               0,         /* accum bits */
  304.                               vislevel   /* level */
  305.                             );
  306.    }
  307.    else if (is_usable_visual( visinfo )) {
  308.       /* Configure this visual as RGB, double-buffered, depth-buffered. */
  309.       /* This is surely wrong for some people's needs but what else */
  310.       /* can be done?  They should use glXChooseVisual(). */
  311.       return save_glx_visual( dpy, visinfo,
  312.                               GL_TRUE,   /* rgb */
  313.                               GL_FALSE,  /* alpha */
  314.                               GL_TRUE,   /* double */
  315.                               8*sizeof(GLdepth),
  316.                               8*sizeof(GLstencil),
  317.                               8*sizeof(GLaccum),
  318.                               0          /* level */
  319.                             );
  320.    }
  321.    else {
  322.       fprintf(stderr,"Mesa: error in glXCreateContext: bad visual\n");
  323.       return NULL;
  324.    }
  325. }
  326.  
  327.  
  328.  
  329. /*
  330.  * Find the GLX visual associated with an XVisualInfo.
  331.  */
  332. static XMesaVisual
  333. find_glx_visual( Display *dpy, XVisualInfo *vinfo )
  334. {
  335.    int i;
  336.  
  337.    /* First try to match pointers */
  338.    for (i=0;i<NumVisuals;i++) {
  339.       if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
  340.          return VisualTable[i];
  341.       }
  342.    }
  343.    /* try to match visual id */
  344.    for (i=0;i<NumVisuals;i++) {
  345.       if (VisualTable[i]->display==dpy
  346.           && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
  347.          return VisualTable[i];
  348.       }
  349.    }
  350.    return NULL;
  351. }
  352.  
  353.  
  354.  
  355.  
  356. /*
  357.  * Determine if a given X window ID is valid (window exists).
  358.  * Do this by calling XGetWindowAttributes() for the window and
  359.  * checking if we catch an X error.
  360.  * Input:  dpy - the display
  361.  *         win - the window to check for existance
  362.  * Return:  GL_TRUE - window exists
  363.  *          GL_FALSE - window doesn't exist
  364.  */
  365. static GLboolean WindowExistsFlag;
  366.  
  367. static int window_exists_err_handler( Display* dpy, XErrorEvent* xerr )
  368. {
  369.    if (xerr->error_code == BadWindow) {
  370.       WindowExistsFlag = GL_FALSE;
  371.    }
  372.    return 0;
  373. }
  374.  
  375. static GLboolean window_exists( Display *dpy, Window win )
  376. {
  377.    XWindowAttributes wa;
  378.    int (*old_handler)( Display*, XErrorEvent* );
  379.    WindowExistsFlag = GL_TRUE;
  380.    old_handler = XSetErrorHandler(window_exists_err_handler);
  381.    XGetWindowAttributes( dpy, win, &wa ); /* dummy request */
  382.    XSetErrorHandler(old_handler);
  383.    return WindowExistsFlag;
  384. }
  385.  
  386.  
  387.  
  388. /*
  389.  * We occasionally call this function to check if any windows in the
  390.  * BufferList have been destroyed.  If so, we can then deallocate
  391.  * the corresponding Mesa ancillary buffers (depth, stencil, accum)
  392.  * We need to do this because there's no way for Xlib to notify us
  393.  * when a window gets destroyed.
  394.  */
  395. static void free_zombie_buffers( void )
  396. {
  397.    GLint i, j;
  398.  
  399.    for (i=0;i<NumBuffers;i++) {
  400.       if (!BufferList[i]->pixmap_flag) {
  401.          Display *dpy = BufferList[i]->xm_visual->display;
  402.          Window win   = BufferList[i]->frontbuffer;
  403.          int exists;
  404.  
  405.          XSync(dpy,False);
  406.          exists = window_exists( dpy, win );
  407.  
  408.          if (!exists) {
  409.             /* found a dead window, free the ancillary info */
  410.             XMesaDestroyBuffer( BufferList[i] );
  411.             /* move remaining buffer entries up one slot */
  412.             for (j=i+1;j<NumBuffers;j++) {
  413.                BufferList[j-1] = BufferList[j];
  414.             }
  415.             NumBuffers--;
  416.             i--;            /* this cancels out the i++ */
  417.          }
  418.       }
  419.    }
  420. }
  421.  
  422.  
  423.  
  424. /*
  425.  * Return the XMesaBuffer which corresponds to the given X drawable.
  426.  * Return NULL if no corresponding XMesaBuffer.
  427.  */
  428. static XMesaBuffer find_buffer( Display *dpy, Drawable d )
  429. {
  430.    GLint i;
  431.  
  432.    for (i=0;i<NumBuffers;i++) {
  433.       if (BufferList[i]->frontbuffer==d) {
  434.          return BufferList[i];
  435.       }
  436.    }
  437.    return NULL;
  438. }
  439.  
  440.  
  441.  
  442. /*
  443.  * Create a new XMesaBuffer from an X drawable.
  444.  * Input:  v - the XMesaVisual
  445.  *         d - the Window or Pixmap
  446.  *         pixmap_flag - GL_TRUE if d is a pixmap, GL_FALSE if d is a window
  447.  *         cmap - the colormap if d is a pixmap, ignored otherwise.
  448.  */
  449. static XMesaBuffer save_buffer( XMesaVisual v, Drawable d,
  450.                                 GLboolean pixmap_flag, Colormap cmap )
  451. {
  452.    XMesaBuffer b;
  453.  
  454.    if (NumBuffers>=MAX_BUFFERS) {
  455.       fprintf( stderr, "GLX Error: maximum number of buffers exceeded\n");
  456.       return NULL;
  457.    }
  458.    if (pixmap_flag) {
  459.       b = XMesaCreatePixmapBuffer( v, d, cmap );
  460.    }
  461.    else {
  462.       b = XMesaCreateWindowBuffer( v, d );
  463.    }
  464.    if (!b) {
  465.       return NULL;
  466.    }
  467.    BufferList[NumBuffers] = b;
  468.    NumBuffers++;
  469.    return b;
  470. }
  471.  
  472.  
  473.  
  474. /*
  475.  * Return the transparent pixel value for a GLX visual.
  476.  * Input:  glxvis - the glx_visual
  477.  * Return:  a pixel value or -1 if no transparent pixel
  478.  */
  479. static int transparent_pixel( XMesaVisual glxvis )
  480. {
  481.    Display *dpy = glxvis->display;
  482.    XVisualInfo *vinfo = glxvis->visinfo;
  483.    Atom overlayVisualsAtom;
  484.    OverlayInfo *overlay_info = NULL;
  485.    int numOverlaysPerScreen;
  486.    Status status;
  487.    Atom actualType;
  488.    int actualFormat;
  489.    unsigned long sizeData, bytesLeft;
  490.    int i;
  491.  
  492.    /*
  493.     * The SERVER_OVERLAY_VISUALS property on the root window contains
  494.     * a list of overlay visuals.  Get that list now.
  495.     */
  496.    overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
  497.    if (overlayVisualsAtom == None) {
  498.       return -1;
  499.    }
  500.  
  501.    status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
  502.                                overlayVisualsAtom, 0L, (long) 10000, False,
  503.                                overlayVisualsAtom, &actualType, &actualFormat,
  504.                                &sizeData, &bytesLeft,
  505.                                (unsigned char **) &overlay_info );
  506.  
  507.    if (status != Success || actualType != overlayVisualsAtom ||
  508.        actualFormat != 32 || sizeData < 4) {
  509.       /* something went wrong */
  510.       XFree(overlay_info);
  511.       return -1;
  512.    }
  513.  
  514.    /* search the overlay visual list for the visual ID of interest */
  515.    numOverlaysPerScreen = sizeData / 4;
  516.    for (i=0;i<numOverlaysPerScreen;i++) {
  517.       OverlayInfo *ov;
  518.       ov = overlay_info + i;
  519.       if (ov->overlay_visual==vinfo->visualid) {
  520.          /* found it! */
  521.          if (ov->transparent_type==0) {
  522.             /* type 0 indicates no transparency */
  523.             XFree(overlay_info);
  524.             return -1;
  525.          }
  526.          else {
  527.             /* ov->value is the transparent pixel */
  528.             XFree(overlay_info);
  529.             return ov->value;
  530.          }
  531.       }
  532.    }
  533.  
  534.    /* The visual ID was not found in the overlay list. */
  535.    XFree(overlay_info);
  536.    return -1;
  537. }
  538.  
  539.  
  540.  
  541. /*
  542.  * Try to get an X visual which matches the given arguments.
  543.  */
  544. static XVisualInfo *get_visual( Display *dpy, int scr,
  545.                     unsigned int depth, int xclass )
  546. {
  547.    XVisualInfo temp;
  548.    long mask;
  549.    int n;
  550.    int default_depth;
  551.    int default_class;
  552.  
  553.    mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
  554.    temp.screen = scr;
  555.    temp.depth = depth;
  556.    temp.CLASS = xclass;
  557.  
  558.    default_depth = DefaultDepth(dpy,scr);
  559.    default_class = DefaultVisual(dpy,scr)->CLASS;
  560.  
  561.    if (depth==default_depth && xclass==default_class) {
  562.       /* try to get root window's visual */
  563.       temp.visualid = DefaultVisual(dpy,scr)->visualid;
  564.       mask |= VisualIDMask;
  565.    }
  566.  
  567.    return XGetVisualInfo( dpy, mask, &temp, &n );
  568. }
  569.  
  570.  
  571.  
  572. /*
  573.  * Retrieve the value of the given environment variable and find
  574.  * the X visual which matches it.
  575.  * Input:  dpy - the display
  576.  *         screen - the screen number
  577.  *         varname - the name of the environment variable
  578.  * Return:  an XVisualInfo pointer to NULL if error.
  579.  */
  580. static XVisualInfo *get_env_visual( Display *dpy, int scr, char *varname )
  581. {
  582.    char *value;
  583.    char type[100];
  584.    int depth, xclass = -1;
  585.    XVisualInfo *vis;
  586.  
  587.    value = getenv( varname );
  588.    if (!value) {
  589.       return NULL;
  590.    }
  591.  
  592.    sscanf( value, "%s %d", type, &depth );
  593.  
  594.    if (strcmp(type,"TrueColor")==0)          xclass = TrueColor;
  595.    else if (strcmp(type,"DirectColor")==0)   xclass = DirectColor;
  596.    else if (strcmp(type,"PseudoColor")==0)   xclass = PseudoColor;
  597.    else if (strcmp(type,"StaticColor")==0)   xclass = StaticColor;
  598.    else if (strcmp(type,"GrayScale")==0)     xclass = GrayScale;
  599.    else if (strcmp(type,"StaticGray")==0)    xclass = StaticGray;
  600.  
  601.    if (xclass>-1 && depth>0) {
  602.       vis = get_visual( dpy, scr, depth, xclass );
  603.       if (vis) {
  604.      return vis;
  605.       }
  606.    }
  607.  
  608.    fprintf( stderr, "Mesa: GLX unable to find visual class=%s, depth=%d.\n",
  609.         type, depth );
  610.    return NULL;
  611. }
  612.  
  613.  
  614.  
  615. /*
  616.  * Select an X visual which satisfies the RGBA/CI flag and minimum depth.
  617.  * Input:  dpy, screen - X display and screen number
  618.  *         rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode
  619.  *         min_depth - minimum visual depth
  620.  *         preferred_class - preferred GLX visual class or DONT_CARE
  621.  * Return:  pointer to an XVisualInfo or NULL.
  622.  */
  623. static XVisualInfo *choose_x_visual( Display *dpy, int screen,
  624.                      GLboolean rgba, int min_depth,
  625.                                      int preferred_class )
  626. {
  627.    XVisualInfo *vis;
  628.    int xclass, visclass;
  629.    int depth;
  630.  
  631.    if (rgba) {
  632.       Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True);
  633.       /* First see if the MESA_RGB_VISUAL env var is defined */
  634.       vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
  635.       if (vis) {
  636.      return vis;
  637.       }
  638.       /* Otherwise, search for a suitable visual */
  639.       if (preferred_class==DONT_CARE) {
  640.          for (xclass=0;xclass<6;xclass++) {
  641.             switch (xclass) {
  642.                case 0:  visclass = TrueColor;    break;
  643.                case 1:  visclass = DirectColor;  break;
  644.                case 2:  visclass = PseudoColor;  break;
  645.                case 3:  visclass = StaticColor;  break;
  646.                case 4:  visclass = GrayScale;    break;
  647.                case 5:  visclass = StaticGray;   break;
  648.             }
  649.             if (min_depth==0) {
  650.                /* start with shallowest */
  651.                for (depth=0;depth<=32;depth++) {
  652.                   if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
  653.                      /* Special case:  try to get 8-bit PseudoColor before */
  654.                      /* 8-bit TrueColor */
  655.                      vis = get_visual( dpy, screen, 8, PseudoColor );
  656.                      if (vis) {
  657.                         return vis;
  658.                      }
  659.                   }
  660.                   vis = get_visual( dpy, screen, depth, visclass );
  661.                   if (vis) {
  662.                      return vis;
  663.                   }
  664.                }
  665.             }
  666.             else {
  667.                /* start with deepest */
  668.                for (depth=32;depth>=min_depth;depth--) {
  669.                   if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
  670.                      /* Special case:  try to get 8-bit PseudoColor before */
  671.                      /* 8-bit TrueColor */
  672.                      vis = get_visual( dpy, screen, 8, PseudoColor );
  673.                      if (vis) {
  674.                         return vis;
  675.                      }
  676.                   }
  677.                   vis = get_visual( dpy, screen, depth, visclass );
  678.                   if (vis) {
  679.                      return vis;
  680.                   }
  681.                }
  682.             }
  683.          }
  684.       }
  685.       else {
  686.          /* search for a specific visual class */
  687.          switch (preferred_class) {
  688.             case GLX_TRUE_COLOR_EXT:    visclass = TrueColor;    break;
  689.             case GLX_DIRECT_COLOR_EXT:  visclass = DirectColor;  break;
  690.             case GLX_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
  691.             case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
  692.             case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
  693.             case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
  694.             default:   return NULL;
  695.          }
  696.          if (min_depth==0) {
  697.             /* start with shallowest */
  698.             for (depth=0;depth<=32;depth++) {
  699.                vis = get_visual( dpy, screen, depth, visclass );
  700.                if (vis) {
  701.                   return vis;
  702.                }
  703.             }
  704.          }
  705.          else {
  706.             /* start with deepest */
  707.             for (depth=32;depth>=min_depth;depth--) {
  708.                vis = get_visual( dpy, screen, depth, visclass );
  709.                if (vis) {
  710.                   return vis;
  711.                }
  712.             }
  713.          }
  714.       }
  715.    }
  716.    else {
  717.       /* First see if the MESA_CI_VISUAL env var is defined */
  718.       vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" );
  719.       if (vis) {
  720.      return vis;
  721.       }
  722.       /* Otherwise, search for a suitable visual, starting with shallowest */
  723.       if (preferred_class==DONT_CARE) {
  724.          for (xclass=0;xclass<4;xclass++) {
  725.             switch (xclass) {
  726.                case 0:  visclass = PseudoColor;  break;
  727.                case 1:  visclass = StaticColor;  break;
  728.                case 2:  visclass = GrayScale;    break;
  729.                case 3:  visclass = StaticGray;   break;
  730.             }
  731.             /* try 8-bit up through 16-bit */
  732.             for (depth=8;depth<=16;depth++) {
  733.                vis = get_visual( dpy, screen, depth, visclass );
  734.                if (vis) {
  735.                   return vis;
  736.                }
  737.             }
  738.             /* try min_depth up to 8-bit */
  739.             for (depth=min_depth;depth<8;depth++) {
  740.                vis = get_visual( dpy, screen, depth, visclass );
  741.                if (vis) {
  742.                   return vis;
  743.                }
  744.             }
  745.          }
  746.       }
  747.       else {
  748.          /* search for a specific visual class */
  749.          switch (preferred_class) {
  750.             case GLX_TRUE_COLOR_EXT:    visclass = TrueColor;    break;
  751.             case GLX_DIRECT_COLOR_EXT:  visclass = DirectColor;  break;
  752.             case GLX_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
  753.             case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
  754.             case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
  755.             case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
  756.             default:   return NULL;
  757.          }
  758.          /* try 8-bit up through 16-bit */
  759.          for (depth=8;depth<=16;depth++) {
  760.             vis = get_visual( dpy, screen, depth, visclass );
  761.             if (vis) {
  762.                return vis;
  763.             }
  764.          }
  765.          /* try min_depth up to 8-bit */
  766.          for (depth=min_depth;depth<8;depth++) {
  767.             vis = get_visual( dpy, screen, depth, visclass );
  768.             if (vis) {
  769.                return vis;
  770.             }
  771.          }
  772.       }
  773.    }
  774.  
  775.    /* didn't find a visual */
  776.    return NULL;
  777. }
  778.  
  779.  
  780.  
  781. /*
  782.  * Find the deepest X over/underlay visual of at least min_depth.
  783.  * Input:  dpy, screen - X display and screen number
  784.  *         level - the over/underlay level
  785.  *         trans_type - transparent pixel type: GLX_NONE_EXT,
  786.  *                      GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT,
  787.  *                      or DONT_CARE
  788.  *         trans_value - transparent pixel value or DONT_CARE
  789.  *         min_depth - minimum visual depth
  790.  *         preferred_class - preferred GLX visual class or DONT_CARE
  791.  * Return:  pointer to an XVisualInfo or NULL.
  792.  */
  793. static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr,
  794.                                              int level, int trans_type,
  795.                                              int trans_value,
  796.                                              int min_depth,
  797.                                              int preferred_class )
  798. {
  799.    Atom overlayVisualsAtom;
  800.    OverlayInfo *overlay_info;
  801.    int numOverlaysPerScreen;
  802.    Status status;
  803.    Atom actualType;
  804.    int actualFormat;
  805.    unsigned long sizeData, bytesLeft;
  806.    int i;
  807.    XVisualInfo *deepvis;
  808.    int deepest;
  809.  
  810.    /*TMP*/ int tt, tv;
  811.  
  812.    switch (preferred_class) {
  813.       case GLX_TRUE_COLOR_EXT:    preferred_class = TrueColor;    break;
  814.       case GLX_DIRECT_COLOR_EXT:  preferred_class = DirectColor;  break;
  815.       case GLX_PSEUDO_COLOR_EXT:  preferred_class = PseudoColor;  break;
  816.       case GLX_STATIC_COLOR_EXT:  preferred_class = StaticColor;  break;
  817.       case GLX_GRAY_SCALE_EXT:    preferred_class = GrayScale;    break;
  818.       case GLX_STATIC_GRAY_EXT:   preferred_class = StaticGray;   break;
  819.       default:                    preferred_class = DONT_CARE;
  820.    }
  821.  
  822.    /*
  823.     * The SERVER_OVERLAY_VISUALS property on the root window contains
  824.     * a list of overlay visuals.  Get that list now.
  825.     */
  826.    overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
  827.    if (overlayVisualsAtom == None) {
  828.       return GL_FALSE;
  829.    }
  830.  
  831.    status = XGetWindowProperty(dpy, RootWindow( dpy, scr ),
  832.                                overlayVisualsAtom, 0L, (long) 10000, False,
  833.                                overlayVisualsAtom, &actualType, &actualFormat,
  834.                                &sizeData, &bytesLeft,
  835.                                (unsigned char **) &overlay_info );
  836.  
  837.    if (status != Success || actualType != overlayVisualsAtom ||
  838.        actualFormat != 32 || sizeData < 4) {
  839.       /* something went wrong */
  840.       return GL_FALSE;
  841.    }
  842.  
  843.    /* Search for the deepest overlay which satisifies all criteria. */
  844.    deepest = min_depth;
  845.    deepvis = NULL;
  846.  
  847.    numOverlaysPerScreen = sizeData / 4;
  848.    for (i=0;i<numOverlaysPerScreen;i++) {
  849.       XVisualInfo *vislist, vistemplate;
  850.       int count;
  851.       OverlayInfo *ov;
  852.       ov = overlay_info + i;
  853.  
  854.       if (ov->layer!=level) {
  855.          /* failed overlay level criteria */
  856.          continue;
  857.       }
  858.       if (!(trans_type==DONT_CARE
  859.             || (trans_type==GLX_TRANSPARENT_INDEX_EXT
  860.                 && ov->transparent_type>0)
  861.             || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) {
  862.          /* failed transparent pixel type criteria */
  863.          continue;
  864.       }
  865.       if (trans_value!=DONT_CARE && trans_value!=ov->value) {
  866.          /* failed transparent pixel value criteria */
  867.          continue;
  868.       }
  869.  
  870.       /* get XVisualInfo and check the depth */
  871.       vistemplate.visualid = ov->overlay_visual;
  872.       vistemplate.screen = scr;
  873.       vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask,
  874.                                 &vistemplate, &count );
  875.  
  876.       if (count!=1) {
  877.          /* something went wrong */
  878.          continue;
  879.       }
  880.       if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) {
  881.          /* wrong visual class */
  882.          continue;
  883.       }
  884.  
  885.       if (deepvis==NULL || vislist->depth > deepest) {
  886.          /* YES!  found a satisfactory visual */
  887.          if (deepvis) {
  888.             free( deepvis );
  889.          }
  890.          deepest = vislist->depth;
  891.          deepvis = vislist;
  892.          /* TMP */  tt = ov->transparent_type;
  893.          /* TMP */  tv = ov->value;
  894.       }
  895.    }
  896.  
  897. /*TMP
  898.    if (deepvis) {
  899.       printf("chose 0x%x:  layer=%d depth=%d trans_type=%d trans_value=%d\n",
  900.              deepvis->visualid, level, deepvis->depth, tt, tv );
  901.    }
  902. */
  903.    return deepvis;
  904. }
  905.  
  906.  
  907.  
  908. /*
  909.  * Return the number of bits set in n.
  910.  */
  911. static int bitcount( unsigned long n )
  912. {
  913.    int bits;
  914.    for (bits=0; n>0; n=n>>1) {
  915.       if (n&1) {
  916.          bits++;
  917.       }
  918.    }
  919.    return bits;
  920. }
  921.  
  922.  
  923.  
  924. XVisualInfo *glXChooseVisual( Display *dpy, int screen, int *list )
  925. {
  926.    int *parselist;
  927.    XVisualInfo *vis;
  928.    int min_ci = 0;
  929.    int min_red=0, min_green=0, min_blue=0;
  930.    GLboolean rgb_flag = GL_FALSE;
  931.    GLboolean alpha_flag = GL_FALSE;
  932.    GLboolean double_flag = GL_FALSE;
  933.    GLint depth_size = 0;
  934.    GLint stencil_size = 0;
  935.    GLint accum_size = 0;
  936.    int level = 0;
  937.    int visual_type = DONT_CARE;
  938.    int trans_type = DONT_CARE;
  939.    int trans_value = DONT_CARE;
  940.  
  941.    parselist = list;
  942.  
  943.    while (*parselist) {
  944.  
  945.       switch (*parselist) {
  946.      case GLX_USE_GL:
  947.         /* ignore */
  948.         parselist++;
  949.         break;
  950.      case GLX_BUFFER_SIZE:
  951.         parselist++;
  952.         min_ci = *parselist++;
  953.         break;
  954.      case GLX_LEVEL:
  955.         parselist++;
  956.             level = *parselist++;
  957.         break;
  958.      case GLX_RGBA:
  959.         rgb_flag = GL_TRUE;
  960.         parselist++;
  961.         break;
  962.      case GLX_DOUBLEBUFFER:
  963.         double_flag = GL_TRUE;
  964.         parselist++;
  965.         break;
  966.      case GLX_STEREO:
  967.         /* not supported */
  968.             return NULL;
  969.      case GLX_AUX_BUFFERS:
  970.         /* ignore */
  971.         parselist++;
  972.         parselist++;
  973.         break;
  974.      case GLX_RED_SIZE:
  975.         parselist++;
  976.         min_red = *parselist++;
  977.         break;
  978.      case GLX_GREEN_SIZE:
  979.         parselist++;
  980.         min_green = *parselist++;
  981.         break;
  982.      case GLX_BLUE_SIZE:
  983.         parselist++;
  984.         min_blue = *parselist++;
  985.         break;
  986.      case GLX_ALPHA_SIZE:
  987.         parselist++;
  988.             {
  989.                GLint size = *parselist++;
  990.                alpha_flag = size>0 ? 1 : 0;
  991.             }
  992.         break;
  993.      case GLX_DEPTH_SIZE:
  994.         parselist++;
  995.         depth_size = *parselist++;
  996.         break;
  997.      case GLX_STENCIL_SIZE:
  998.         parselist++;
  999.         stencil_size = *parselist++;
  1000.         break;
  1001.      case GLX_ACCUM_RED_SIZE:
  1002.      case GLX_ACCUM_GREEN_SIZE:
  1003.      case GLX_ACCUM_BLUE_SIZE:
  1004.      case GLX_ACCUM_ALPHA_SIZE:
  1005.         parselist++;
  1006.             {
  1007.                GLint size = *parselist++;
  1008.                accum_size = MAX2( accum_size, size );
  1009.             }
  1010.         break;
  1011.  
  1012.          /*
  1013.           * GLX_EXT_visual_info extension
  1014.           */
  1015.          case GLX_X_VISUAL_TYPE_EXT:
  1016.             parselist++;
  1017.             visual_type = *parselist++;
  1018.             break;
  1019.          case GLX_TRANSPARENT_TYPE_EXT:
  1020.             parselist++;
  1021.             trans_type = *parselist++;
  1022.             break;
  1023.          case GLX_TRANSPARENT_INDEX_VALUE_EXT:
  1024.             parselist++;
  1025.             trans_value = *parselist++;
  1026.             break;
  1027.          case GLX_TRANSPARENT_RED_VALUE_EXT:
  1028.          case GLX_TRANSPARENT_GREEN_VALUE_EXT:
  1029.          case GLX_TRANSPARENT_BLUE_VALUE_EXT:
  1030.          case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
  1031.         /* ignore */
  1032.         parselist++;
  1033.         parselist++;
  1034.         break;
  1035.          
  1036.      case None:
  1037.         break;
  1038.      default:
  1039.         /* undefined attribute */
  1040.         return NULL;
  1041.       }
  1042.    }
  1043.  
  1044.    /*
  1045.     * Since we're only simulating the GLX extension this function will never
  1046.     * find any real GL visuals.  Instead, all we can do is try to find an RGB
  1047.     * or CI visual of appropriate depth.  Other requested attributes such as
  1048.     * double buffering, depth buffer, etc. will be associated with the X
  1049.     * visual and stored in the VisualTable[].
  1050.     */
  1051.    if (level==0) {
  1052.       /* normal color planes */
  1053.       if (rgb_flag) {
  1054.          /* Get an RGB visual */
  1055.          int min_rgb = min_red + min_green + min_blue;
  1056.          if (min_rgb>1 && min_rgb<8) {
  1057.             /* a special case to be sure we can get a monochrome visual */
  1058.             min_rgb = 1;
  1059.          }
  1060.          vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type );
  1061.       }
  1062.       else {
  1063.          /* Get a color index visual */
  1064.          vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type );
  1065.          accum_size = 0;
  1066.       }
  1067.    }
  1068.    else {
  1069.       /* over/underlay planes */
  1070.       vis = choose_x_overlay_visual( dpy, screen, level, trans_type,
  1071.                                      trans_value, min_ci, visual_type );
  1072.    }
  1073.  
  1074.    if (vis) {
  1075.       if (!save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
  1076.                             depth_size, stencil_size, accum_size, level ))
  1077.          return NULL;
  1078.    }
  1079.  
  1080.    return vis;
  1081. }
  1082.  
  1083.  
  1084.  
  1085.  
  1086. GLXContext glXCreateContext( Display *dpy, XVisualInfo *visinfo,
  1087.                  GLXContext share_list, Bool direct )
  1088. {
  1089.    XMesaVisual glxvis;
  1090.  
  1091.    /* Garbage collection */
  1092.    free_zombie_buffers();
  1093.  
  1094.    glxvis = find_glx_visual( dpy, visinfo );
  1095.    if (!glxvis) {
  1096.       /* This visual wasn't found with glXChooseVisual() */
  1097.       glxvis = create_glx_visual( dpy, visinfo );
  1098.       if (!glxvis) {
  1099.          /* unusable visual */
  1100.          return NULL;
  1101.       }
  1102.    }
  1103.    return (GLXContext) XMesaCreateContext( glxvis, (XMesaContext) share_list );
  1104. }
  1105.  
  1106.  
  1107.  
  1108. Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
  1109. {
  1110.    if (ctx && drawable) {
  1111.       static GLXDrawable prev_drawable = 0;
  1112.       static XMesaBuffer prev_buffer = 0;
  1113.       XMesaBuffer buffer;
  1114.  
  1115.       if (drawable==prev_drawable) {
  1116.          buffer = prev_buffer;
  1117.       }
  1118.       else {
  1119.          buffer = find_buffer( dpy, drawable );
  1120.       }
  1121.       if (!buffer) {
  1122.          /* drawable must be a new window! */
  1123.          buffer = save_buffer( ctx->xm_visual, drawable, GL_FALSE, 0 );
  1124.          if (!buffer) {
  1125.             /* If this happens, increase MAX_BUFFERS and recompile */
  1126.             fprintf(stderr,"Mesa GLX error: too many windows!\n");
  1127.             return False;
  1128.          }
  1129.       }
  1130.       prev_drawable = drawable;
  1131.       prev_buffer = buffer;
  1132.  
  1133.       /* Now make current! */
  1134.       return (Bool) XMesaMakeCurrent( (XMesaContext) ctx, buffer );
  1135.    }
  1136.    else if (!ctx && !drawable) {
  1137.       /* release current context w/out assigning new one. */
  1138.       XMesaMakeCurrent( NULL, NULL );
  1139.       return True;
  1140.    }
  1141.    else {
  1142.       /* ctx XOR drawable is NULL, this is an error */
  1143.       return False;
  1144.    }
  1145. }
  1146.  
  1147.  
  1148.  
  1149. GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo,
  1150.                               Pixmap pixmap )
  1151. {
  1152.    XMesaVisual v;
  1153.    XMesaBuffer b;
  1154.  
  1155.    v = find_glx_visual( dpy, visinfo );
  1156.    if (!v) {
  1157.       v = create_glx_visual( dpy, visinfo );
  1158.       if (!v) {
  1159.          /* unusable visual */
  1160.          return 0;
  1161.       }
  1162.    }
  1163.  
  1164.    b = save_buffer( v, pixmap, GL_TRUE, 0 );
  1165.    if (!b) {
  1166.       return 0;
  1167.    }
  1168.    return b->frontbuffer;
  1169. }
  1170.  
  1171.  
  1172. #ifdef GLX_MESA_pixmap_colormap
  1173.  
  1174. GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
  1175.                                   Pixmap pixmap, Colormap cmap )
  1176. {
  1177.    XMesaVisual v;
  1178.    XMesaBuffer b;
  1179.  
  1180.    v = find_glx_visual( dpy, visinfo );
  1181.    if (!v) {
  1182.       v = create_glx_visual( dpy, visinfo );
  1183.       if (!v) {
  1184.          /* unusable visual */
  1185.          return 0;
  1186.       }
  1187.    }
  1188.  
  1189.    b = save_buffer( v, pixmap, GL_TRUE, cmap );
  1190.    if (!b) {
  1191.       return 0;
  1192.    }
  1193.    return b->frontbuffer;
  1194. }
  1195.  
  1196. #endif
  1197.  
  1198.  
  1199. void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
  1200. {
  1201.    int i, j;
  1202.  
  1203.    for (i=0;i<NumBuffers;i++) {
  1204.       if (BufferList[i]->frontbuffer==pixmap) {
  1205.          XMesaDestroyBuffer( BufferList[i] );
  1206.      for (j=i+1;j<NumBuffers;j++) {
  1207.         BufferList[j-1] = BufferList[j];
  1208.      }
  1209.      NumBuffers--;
  1210.      return;
  1211.       }
  1212.    }
  1213.    fprintf( stderr, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
  1214. }
  1215.  
  1216.  
  1217. void glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
  1218.              GLuint mask )
  1219. {
  1220.    XMesaContext xm_src, xm_dst;
  1221.    xm_src = (XMesaContext) src;
  1222.    xm_dst = (XMesaContext) dst;
  1223.    gl_copy_context( xm_src->gl_ctx, xm_dst->gl_ctx, mask );
  1224. }
  1225.  
  1226.  
  1227.  
  1228. Bool glXQueryExtension( Display *dpy, int *errorb, int *event )
  1229. {
  1230.    /* Mesa's GLX isn't really an X extension but we try to act like one. */
  1231.    return True;
  1232. }
  1233.  
  1234.  
  1235. void glXDestroyContext( Display *dpy, GLXContext ctx )
  1236. {
  1237.    XMesaDestroyContext( (XMesaContext) ctx );
  1238.  
  1239.    /* Garbage collection */
  1240.    free_zombie_buffers();
  1241. }
  1242.  
  1243.  
  1244.  
  1245. Bool glXIsDirect( Display *dpy, GLXContext ctx )
  1246. {
  1247.    /* This isn't true but... */
  1248.    return True;
  1249. }
  1250.  
  1251.  
  1252.  
  1253. void glXSwapBuffers( Display *dpy, GLXDrawable drawable )
  1254. {
  1255.    static GLXDrawable prev_drawable = 0;
  1256.    static XMesaBuffer prev_buffer = 0;
  1257.  
  1258.    if (drawable==prev_drawable) {
  1259.       XMesaSwapBuffers( prev_buffer );
  1260.       return;
  1261.    }
  1262.  
  1263.    prev_drawable = drawable;
  1264.    prev_buffer = find_buffer( dpy, drawable );
  1265.    if (prev_buffer) {
  1266.       XMesaSwapBuffers( prev_buffer );
  1267.    }
  1268.    else {
  1269.       fprintf( stderr,
  1270.       "Warning: glXSwapBuffers drawable doesn't match current context\n");
  1271.    }
  1272. }
  1273.  
  1274.  
  1275.  
  1276. Bool glXQueryVersion( Display *dpy, int *maj, int *min )
  1277. {
  1278.    /* Return GLX version, not Mesa version */
  1279.    *maj = 1;
  1280.    *min = 1;
  1281.    return True;
  1282. }
  1283.  
  1284.  
  1285.  
  1286. /*
  1287.  * Query the GLX attributes of the given XVisualInfo.
  1288.  */
  1289. int glXGetConfig( Display *dpy, XVisualInfo *visinfo,
  1290.           int attrib, int *value )
  1291. {
  1292.    int visclass;
  1293.    XMesaVisual glxvis;
  1294.  
  1295.    glxvis = find_glx_visual( dpy, visinfo );
  1296.    if (!glxvis) {
  1297.       /* this visual wasn't obtained with glXChooseVisual */
  1298.       glxvis = create_glx_visual( dpy, visinfo );
  1299.       if (!glxvis) {
  1300.      /* this visual can't be used for GL rendering */
  1301.      if (attrib==GLX_USE_GL) {
  1302.         *value = (int) False;
  1303.         return 0;
  1304.      }
  1305.      else {
  1306.         /*fprintf( stderr, "Mesa: Error in glXGetConfig: bad visual\n");*/
  1307.         return GLX_BAD_VISUAL;
  1308.      }
  1309.       }
  1310.    }
  1311.  
  1312.    /* Get the visual class */
  1313.    visclass = visinfo->CLASS;
  1314.  
  1315.    switch(attrib) {
  1316.       case GLX_USE_GL:
  1317.          *value = (int) True;
  1318.      return 0;
  1319.       case GLX_BUFFER_SIZE:
  1320.      *value = visinfo->depth;
  1321.      return 0;
  1322.       case GLX_LEVEL:
  1323.      *value = glxvis->level;
  1324.      return 0;
  1325.       case GLX_RGBA:
  1326.      if (glxvis->gl_visual->RGBAflag) {
  1327.         *value = True;
  1328.      }
  1329.      else {
  1330.         *value = False;
  1331.      }
  1332.      return 0;
  1333.       case GLX_DOUBLEBUFFER:
  1334.      *value = (int) glxvis->gl_visual->DBflag;
  1335.      return 0;
  1336.       case GLX_STEREO:
  1337.      *value = (int) False;
  1338.      return 0;
  1339.       case GLX_AUX_BUFFERS:
  1340.      *value = (int) False;
  1341.      return 0;
  1342.       case GLX_RED_SIZE:
  1343.          if (visclass==DirectColor || visclass==TrueColor) {
  1344.             *value = bitcount( visinfo->visual->red_mask );
  1345.          }
  1346.          else {
  1347.             /* a crude approximation */
  1348.             *value = visinfo->depth;
  1349.          }
  1350.      return 0;
  1351.       case GLX_GREEN_SIZE:
  1352.          if (visclass==DirectColor || visclass==TrueColor) {
  1353.             *value = bitcount( visinfo->visual->green_mask );
  1354.          }
  1355.          else {
  1356.             *value = visinfo->depth;
  1357.          }
  1358.      return 0;
  1359.       case GLX_BLUE_SIZE:
  1360.          if (visclass==DirectColor || visclass==TrueColor) {
  1361.             *value = bitcount( visinfo->visual->blue_mask );
  1362.          }
  1363.          else {
  1364.             *value = visinfo->depth;
  1365.          }
  1366.      return 0;
  1367.       case GLX_ALPHA_SIZE:
  1368.          if (glxvis->gl_visual->FrontAlphaEnabled ||
  1369.              glxvis->gl_visual->BackAlphaEnabled) {
  1370.             *value = 8;
  1371.          }
  1372.          else {
  1373.             *value = 0;
  1374.          }
  1375.      return 0;
  1376.       case GLX_DEPTH_SIZE:
  1377.          *value = glxvis->gl_visual->DepthBits;
  1378.      return 0;
  1379.       case GLX_STENCIL_SIZE:
  1380.      *value = glxvis->gl_visual->StencilBits;
  1381.      return 0;
  1382.       case GLX_ACCUM_RED_SIZE:
  1383.       case GLX_ACCUM_GREEN_SIZE:
  1384.       case GLX_ACCUM_BLUE_SIZE:
  1385.       case GLX_ACCUM_ALPHA_SIZE:
  1386.      *value = glxvis->gl_visual->AccumBits;
  1387.      return 0;
  1388.  
  1389.       /*
  1390.        * GLX_EXT_visual_info extension
  1391.        */
  1392.       case GLX_X_VISUAL_TYPE_EXT:
  1393.          switch (glxvis->visinfo->CLASS) {
  1394.             case StaticGray:   *value = GLX_STATIC_GRAY_EXT;   return 0;
  1395.             case GrayScale:    *value = GLX_GRAY_SCALE_EXT;    return 0;
  1396.             case StaticColor:  *value = GLX_STATIC_GRAY_EXT;   return 0;
  1397.             case PseudoColor:  *value = GLX_PSEUDO_COLOR_EXT;  return 0;
  1398.             case TrueColor:    *value = GLX_TRUE_COLOR_EXT;    return 0;
  1399.             case DirectColor:  *value = GLX_DIRECT_COLOR_EXT;  return 0;
  1400.          }
  1401.          return 0;
  1402.       case GLX_TRANSPARENT_TYPE_EXT:
  1403.          if (glxvis->level==0) {
  1404.             /* normal planes */
  1405.             *value = GLX_NONE_EXT;
  1406.          }
  1407.          else if (glxvis->level>0) {
  1408.             /* overlay */
  1409.             if (glxvis->gl_visual->RGBAflag) {
  1410.                *value = GLX_TRANSPARENT_RGB_EXT;
  1411.             }
  1412.             else {
  1413.                *value = GLX_TRANSPARENT_INDEX_EXT;
  1414.             }
  1415.          }
  1416.          else if (glxvis->level<0) {
  1417.             /* underlay */
  1418.             *value = GLX_NONE_EXT;
  1419.          }
  1420.          return 0;
  1421.       case GLX_TRANSPARENT_INDEX_VALUE_EXT:
  1422.          {
  1423.             int pixel = transparent_pixel( glxvis );
  1424.             if (pixel>=0) {
  1425.                *value = pixel;
  1426.             }
  1427.             /* else undefined */
  1428.          }
  1429.          return 0;
  1430.       case GLX_TRANSPARENT_RED_VALUE_EXT:
  1431.          /* undefined */
  1432.          return 0;
  1433.       case GLX_TRANSPARENT_GREEN_VALUE_EXT:
  1434.          /* undefined */
  1435.          return 0;
  1436.       case GLX_TRANSPARENT_BLUE_VALUE_EXT:
  1437.          /* undefined */
  1438.          return 0;
  1439.       case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
  1440.          /* undefined */
  1441.          return 0;
  1442.  
  1443.       /*
  1444.        * Extensions
  1445.        */
  1446.       default:
  1447.      return GLX_BAD_ATTRIBUTE;
  1448.    }
  1449. }
  1450.  
  1451.  
  1452.  
  1453. GLXContext glXGetCurrentContext( void )
  1454. {
  1455.    return (GLXContext) XMesaGetCurrentContext();
  1456. }
  1457.  
  1458.  
  1459.  
  1460. GLXDrawable glXGetCurrentDrawable( void )
  1461. {
  1462.    XMesaBuffer b = XMesaGetCurrentBuffer();
  1463.    if (b) {
  1464.       return b->frontbuffer;
  1465.    }
  1466.    else {
  1467.       return 0;
  1468.    }
  1469. }
  1470.  
  1471.  
  1472. void glXWaitGL( void )
  1473. {
  1474.    XMesaContext xmesa = XMesaGetCurrentContext();
  1475.    XMesaFlush( xmesa );
  1476. }
  1477.  
  1478.  
  1479.  
  1480. void glXWaitX( void )
  1481. {
  1482.    XMesaContext xmesa = XMesaGetCurrentContext();
  1483.    XMesaFlush( xmesa );
  1484. }
  1485.  
  1486.  
  1487.  
  1488. #define EXTENSIONS "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_MESA_release_buffers"
  1489.  
  1490.  
  1491. /* GLX 1.1 and later */
  1492. const char *glXQueryExtensionsString( Display *dpy, int screen )
  1493. {
  1494.    static char *extensions = EXTENSIONS;
  1495.    return extensions;
  1496. }
  1497.  
  1498.  
  1499.  
  1500. /* GLX 1.1 and later */
  1501. const char *glXQueryServerString( Display *dpy, int screen, int name )
  1502. {
  1503.    static char *extensions = EXTENSIONS;
  1504.    static char *vendor = "Brian Paul";
  1505.    static char *version = "1.1 Mesa 2.2";
  1506.  
  1507.    switch (name) {
  1508.       case GLX_EXTENSIONS:
  1509.          return extensions;
  1510.       case GLX_VENDOR:
  1511.      return vendor;
  1512.       case GLX_VERSION:
  1513.      return version;
  1514.       default:
  1515.          return NULL;
  1516.    }
  1517. }
  1518.  
  1519.  
  1520.  
  1521. /* GLX 1.1 and later */
  1522. const char *glXGetClientString( Display *dpy, int name )
  1523. {
  1524.    static char *extensions = EXTENSIONS;
  1525.    static char *vendor = "Brian Paul";
  1526.    static char *version = "1.1 Mesa 2.2";
  1527.  
  1528.    switch (name) {
  1529.       case GLX_EXTENSIONS:
  1530.          return extensions;
  1531.       case GLX_VENDOR:
  1532.      return vendor;
  1533.       case GLX_VERSION:
  1534.      return version;
  1535.       default:
  1536.          return NULL;
  1537.    }
  1538. }
  1539.  
  1540.  
  1541.  
  1542. /*
  1543.  * Release the depth, stencil, accum buffers attached to a window prior
  1544.  * to destroying the window.
  1545.  */
  1546. Bool glXReleaseBuffersMESA( Display *dpy, Window w )
  1547. {
  1548.    GLint i, j;
  1549.  
  1550.    for (i=0;i<NumBuffers;i++) {
  1551.       if (BufferList[i]->frontbuffer==w) {
  1552.          XMesaDestroyBuffer( BufferList[i] );
  1553.      for (j=i+1;j<NumBuffers;j++) {
  1554.         BufferList[j-1] = BufferList[j];
  1555.      }
  1556.      NumBuffers--;
  1557.          return True;
  1558.       }
  1559.    }
  1560.    return False;
  1561. }
  1562.  
  1563.